package com.example.bitmap;

import java.util.BitSet;

/**
 * 位运算工具类
 * @author shanchong
 * @date 2021/1/28
 **/
public class BitUtils {

    public static void main(String[] args) {
        System.out.println(match("0010101110", 1));
        System.out.println(match("11101111","001","010","100"));
        System.out.println(match("11101111","1111","010","100"));
        BitSet join = join("010", "001", "000");
        System.out.println(bitsetToString(join));
        BitSet bitSet = stringToBitset("1011111111111111111111111111111111111111111111111111111111111101111101010111111111111111111111111111111111111111111111111111111111111110111110101011111111111111111111111111111111111111111111111111111111111111011111010101111111111111111111111111111111111111111111111111111111111111101111101010");
        System.out.println(bitsetToString(bitSet));
        BitSet bitSet1 = stringToBitset("11101111");
        BitSet bitSet2 = stringToBitset("1111");
        System.out.println(match(bitSet1, bitSet2));
    }

    /**
     * 二进制字符串转化为bitset
     * @param bit 二进制字符串
     * @return bitset
     */
    public static BitSet stringToBitset(String bit) {
        int length = bit.length();
        if (length == 0) {
            return new BitSet();
        }
        int il = length / 63 + 1;
        long[] longs = new long[il];
        for (int i = 0; i < il; i++) {
            String substring = bit.substring(i * 63, Math.min((i + 1) * 63,length));
            longs[i] = Long.valueOf(substring, 2);
        }
        return BitSet.valueOf(longs);
    }

    /**
     * bitset转换成二进制字符串
     * @param bitSet bitset
     * @return  二进制字符串
     */
    public static String bitsetToString(BitSet bitSet) {
        StringBuilder stringBuilder = new StringBuilder();
        for (final long aLong : bitSet.toLongArray()) {
            stringBuilder.append(Long.toBinaryString(aLong));
        }
        return stringBuilder.toString();
    }

    /**
     * 根据索引判断是否匹配
     * @param bit 二进制字符串
     * @param index 索引
     * @return 当匹配时返回true
     */
    public static boolean match(String bit, int index) {
        BitSet bitSet = stringToBitset(bit);
        return bitSet.get(index);
    }

    public static boolean match(BitSet bitSet1, BitSet bitSet2) {
        bitSet1.and(bitSet2);
        return bitSet1.equals(bitSet2);
    }

    /**
     * 两个二进制字符串之间进行判断
     * 判断bit是否满足bit2
     * @param bit 被参考
     *            长度不能超过64
     * @param bits 参考的
     *             长度不能超过64
     * @return 当匹配时返回true
     */
    public static boolean match(String bit, String... bits) {
        BitSet bitSet = stringToBitset(bit);
        BitSet bitSet1 = join(bits);
        bitSet.and(bitSet1);
        return bitSet.equals(bitSet1);
    }

    /**
     * 合并多个二进制字符串
     * @param bits 二进制字符串
     * @return bitset
     */
    public static BitSet join(String... bits) {
        BitSet bitSet = new BitSet();
        for (final String bit : bits) {
            bitSet.or(stringToBitset(bit));
        }
        return bitSet;
    }
}
